//
//  mcast_service_process.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2013-2014 Razvan Coca (razvan dot coca at  gmail dot com)
// This is mostly generated code. Generator is distributed under GPL. Edit it to suit your needs.
// 


#ifndef mcast_service_process_hpp
#define mcast_service_process_hpp
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

#include "patterns/command.hpp"
#include "patterns/handlers.hpp"

#include "logging/logging.hpp"

namespace pcmd=patterns::command;
namespace phdl=patterns::handlers;
namespace ba=boost::asio;
namespace bs=boost::system;
namespace bt=boost::posix_time;

#include "components/defs/util_types.hpp"
#include "components/defs/server_processor.hpp"
#include "components/protocol/recv_client_request.hpp"
#include "components/protocol/server_send_reply.hpp"

#include "components/defs/handler_types.hpp"

namespace components{
namespace service{



class mcast_service_process :public boost::enable_shared_from_this<mcast_service_process>, private boost::noncopyable
{
private:
    std::string name_;

    ba::io_service& ios_;

    udp_endpoint_t& local_if_;

    udp_endpoint_t& mgroup_;

    int ttl_;

    crypto_buf_t& iv_;

    crypto_buf_t& key_;

    stats_message_server_processor& message_processor_;

    ba::ip::udp::socket msocket_;

    boost::shared_ptr<components::protocol::server_send_reply> server_send_reply_;

    boost::shared_ptr<components::protocol::recv_client_request> recv_client_request_;

    mcast_service_process (ba::io_service& ios, udp_endpoint_t& local_if, udp_endpoint_t& mgroup, int ttl, crypto_buf_t& iv, crypto_buf_t& key, stats_message_server_processor& message_processor) ;
    pcmd::action_t op_recv_client_request;
public:
    typedef boost::shared_ptr<mcast_service_process> pointer;

    bool cancel () ;

    static boost::shared_ptr<mcast_service_process> create (ba::io_service& ios, udp_endpoint_t& local_if, udp_endpoint_t& mgroup, int ttl, crypto_buf_t& iv, crypto_buf_t& key, stats_message_server_processor& message_processor) ;

    void handle_recv_client_request (const bs::error_code& ec, const crypto_error& eec) ;

    void handle_server_send_reply (const bs::error_code& ec, const crypto_error& eec) ;

    void init_components () ;

    virtual  ~mcast_service_process () ;

 template<typename Handler >
      bool exec(Handler& handler) {
        try{
            LOG(INFO)<<name_<<"::"<<__FUNCTION__;
            init_components();
            phdl::system_crypto_handler_t
                bound_handle_recv_client_request = boost::bind(&mcast_service_process::handle_recv_client_request,shared_from_this(),_1,_2);
            phdl::system_crypto_handler_t
                bound_handle_server_send_reply = boost::bind(&mcast_service_process::handle_server_send_reply,shared_from_this(),_1,_2);

            phdl::system_crypto_handler_t
                    composed_send=phdl::branch_compose(bound_handle_server_send_reply,handler,{});
            pcmd::action_t op_server_send_reply = pcmd::wrap(server_send_reply_,composed_send);

            phdl::system_crypto_handler_t
                    composed_recv=phdl::branch_compose(bound_handle_recv_client_request,handler,op_server_send_reply,{0});
            op_recv_client_request = pcmd::wrap(recv_client_request_,composed_recv);
            return pcmd::invoke(op_recv_client_request);
        }
        catch(std::exception &e){
           LOG(WARNING)<<name_<<"::"<<__FUNCTION__<<":"<<e.what();
           cancel();
           return false;
        }
        
    }
};

}//end namespace service
}//end namespace components

#endif /*#ifdef mcast_service_process_hpp*/
